package com.yyn.seckill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.sun.org.apache.xpath.internal.operations.Or;
import com.yyn.seckill.config.exceptionhandler.CustomException;
import com.yyn.seckill.entity.Goods;
import com.yyn.seckill.entity.Order;
import com.yyn.seckill.entity.SeckillGoods;
import com.yyn.seckill.entity.SeckillOrder;
import com.yyn.seckill.entity.dto.GoodDetialListDto;
import com.yyn.seckill.entity.dto.GoodListDto;
import com.yyn.seckill.entity.dto.SeckillMessage;
import com.yyn.seckill.mapper.OrderMapper;
import com.yyn.seckill.rabbitmq.SeckillSender;
import com.yyn.seckill.service.GoodsService;
import com.yyn.seckill.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yyn.seckill.service.SeckillGoodsService;
import com.yyn.seckill.service.SeckillOrderService;
import com.yyn.seckill.util.JsonUtil;
import com.yyn.seckill.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yyn
 * @since 2023-01-21
 */
@Transactional
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private SeckillGoodsService seckillGoodsService;

    @Autowired
    private SeckillOrderService seckillOrderService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public Order getOrder(Long userId, Long goodId) {

        //        2、判断该用户是否已抢购
//        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        orderLambdaQueryWrapper.eq(Order::getUserId, userId);
//        orderLambdaQueryWrapper.eq(Order::getGoodsId, goodId);
//        int count = this.count(orderLambdaQueryWrapper);
//        用redis解决一个人重复购买的情况
//        Order orderCheck = (Order) redisTemplate.opsForValue().get("orderId=userId:" + userId + "goodId:" + goodId);
//        if (!StringUtils.isEmpty(orderCheck)) {
//            throw new CustomException(20001, "已抢购 不能重复抢");
//        }
////        redis预减库存 递减  =0时还会递减为-1才进行报错
//        Long stock = redisTemplate.opsForValue().decrement("goodListStock:" + goodId);
//        if(stock < 0){
////            为了不出现负数-1  我们给他＋1 好看点
//            redisTemplate.opsForValue().increment("goodListStock:" + goodId,stock);
//            throw new CustomException(20001,"库存已无");
//        }
//        SeckillMessage seckillMessage = new SeckillMessage(userId,goodId);
//        seckillSender.sendSeckillMessage(JsonUtil.object2JsonStr(seckillMessage));
//        先把库存减1再删除订单 以免多下单了
        boolean seckillGoodsResult = seckillGoodsService.update(new UpdateWrapper<SeckillGoods>()
                .setSql("stock_count = " + "stock_count-1")//秒杀库存减1
                .eq("goods_id", goodId).gt("stock_count", 0));//给一个条件  数量大于0再对数据库操作
        if (!seckillGoodsResult) {
            redisTemplate.opsForValue().set("isStockEmpty:"+goodId,"库存已空");
            throw new CustomException(20001, "库存已无");
        }
//        如果库存够了再进行订单的生成
        Goods goods = goodsService.getById(goodId);
//        3、生成订单
        Order order = new Order();
        order.setUserId(Long.valueOf(userId));
        order.setGoodsId(goods.getId());
        order.setDeliveryAddrId(0L);
        order.setGoodsName(goods.getGoodsName());
        order.setGoodsCount(1);//只能买一件
        order.setGoodsPrice(goods.getGoodsPrice());
        order.setOrderChannel(0);
        order.setStatus(0);
        order.setCreateDate(new Date());
        this.save(order);//存数据库
        redisTemplate.opsForValue().set("orderId=userId:" + userId + "goodId:" + goodId, order);//存redis
//        生成秒杀商品与订单的关联表
        SeckillOrder seckillOrder = new SeckillOrder();
        seckillOrder.setUserId(Long.valueOf(userId));
        seckillOrder.setOrderId(order.getId());
        seckillOrder.setGoodsId(goods.getId());
        seckillOrderService.save(seckillOrder);//存数据库

        return order;
    }
}
